package com.news.sentiment.util;

import com.news.sentiment.pojo.User;
import io.jsonwebtoken.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class JwtUtil {
    public static String createJWT(long ttlMillis, User user){
        //设置签名算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        //生成JWT的时间
        long nowMillis = System.currentTimeMillis();
        Date nowDate = new Date(nowMillis);

        Map<String,Object> claims = new HashMap<String,Object>();
        claims.put("userid",user.getUserid());
        claims.put("username",user.getUsername());
        claims.put("password",user.getPassword());

        //生成签名的时候使用的秘钥secret,这个方法本地封装了的，一般可以从本地配置文件中读取，切记这个秘钥不能外露哦。它就是你服务端的私钥，在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
        String key = user.getPassword();

        //生成签发人
        String subject = user.getUsername();

        JwtBuilder builder = Jwts.builder()
                //如果有私有声明，一定要先设置这个自己创建的私有的声明，这个是给builder的claim赋值，一旦写在标准的声明赋值之后，就是覆盖了那些标准的声明的
                .setClaims(claims)
                //设置jti(JWT ID)：是JWT的唯一标识，根据业务需要，这个可以设置为一个不重复的值，主要用来作为一次性token,从而回避重放攻击。
                .setId(UUID.randomUUID().toString())
                //iat: jwt的签发时间
                .setIssuedAt(nowDate)
                //代表这个JWT的主体，即它的所有人，这个是一个json格式的字符串，可以存放什么userid，roldid之类的，作为什么用户的唯一标志。
                .setSubject(subject)
                //设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, key);

        if(ttlMillis>=0){
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            //设置过期时间
            builder.setExpiration(expDate);
        }

        return builder.compact();
    }

    public static Claims paraseJWT(String token,User user){
        String key = user.getPassword();
        Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
        return  claims;
    }
}
